# -*- coding: utf-8 -*-
#   单表简易编辑，增删，改，查
# @Time    ： 2025/11/12  18:50
# @Auther  ： 徐良
# File     :  oneTableEdit.py

from typing import Optional, Union, Dict, Any
from PySide6.QtCore import Signal, Slot, QItemSelection, QModelIndex, QTimer
from PySide6.QtSql import QSqlRecord, QSqlField
from utils.alone.aloneWorkAssistant import AloneWorkAssistant
from utils.commonBillClass import CommonBillClass
from systemSet.ui.onePanelUI import Ui_Form
from PySide6.QtWidgets import QApplication, QTreeWidgetItem
from baseClass.winPanel.baseQWidget import BaseQWidget
from baseClass.tree.build_tree import AsyncTreeLoader
from baseClass.tools.dialogUtils import DialogUtils, StandardButton
from baseClass.winPanel.interface_style import apply_styles
from baseClass.business.saveBill import SaveTableAction
from baseClass.business.sqlParseTool import SqlParseTool
from baseClass.delegate.defineDelegate import DefineFeldDelegate
from dbService.db_service import get_model



class OneTableEdit(BaseQWidget, AloneWorkAssistant, CommonBillClass, Ui_Form):

    def __init__(self, p_dict:Dict[str, Any]=None,parent=None):

        super().__init__(parent)
        self.update_set = set()
        self.del_set = set()
        self.dirty = False
        self._is_data_changed_connected = False  # 信号连接标志位

        self.tree_loader = None
        self._tree_connected = False
        self.DEFAULT_MS_DICT = p_dict
        self.ms_number = self.DEFAULT_MS_DICT.get('ms_number')
        # 创建工作类并初始化
        # self.create_factory(self.DEFAULT_MS_DICT)
        # 创建单表工作类并初始化
        self.create_table_work_class(self.DEFAULT_MS_DICT)

        self.checkBox.stateChanged.connect(self.on_check_box_state_changed)
        self._init_map()
        self._read_data()
        self.load_tree()
        self._init_panel()
        apply_styles(self)


    def _init_map(self) -> None:
        """
        关系映射
        :return:
        """
        # 表名，是否为树结构，sql_name名
        self.table_name = {
            '81.01.01': ('t_navigation','tree','navigationSql',),
            '81.01.02': ('t_menu', 'tree', 'menuSql',),
            '81.01.03': ('t_action', 'tree', 'actionSql',),
            '81.01.04': ('t_domain', 'None', 'domainSql',)
        }


    # region    建树，树点击事件, 初始面板
    # 建树
    def load_tree(self) -> None:
        table_name, tree_flag, _ = self.table_name.get(self.ms_number)
        if tree_flag != 'tree':
            self.treeWidget.setVisible(False)
            return

        sql = f"SELECT FId, FParentId, FNumber, FName FROM {table_name} ORDER BY FNumber"

        self.tree_loader = AsyncTreeLoader(sql, self.treeWidget)
        QTimer.singleShot(100, self.tree_loader.start)

        # 先断开旧模型连接（若存在）
        if self._tree_connected:
            self.treeWidget.itemDoubleClicked.disconnect(self.on_tree_item_click)
            self._tree_connected = False  # 重置标志位

        if not self._tree_connected:
            self.treeWidget.itemDoubleClicked.connect(self.on_tree_item_click)

    def on_tree_item_click(self, item: QTreeWidgetItem, index: int) -> None:
        """

        :param self:
        :param item:
        :param index:
        :return:
        """
        number = item.text(0)
        i_len = len(number)
        condition = f" SUBSTR(FNumber, 1, {i_len})='{number}'"

        _, _, sql_name = self.table_name.get(self.ms_number)


        sql = self.get_sql(sql_name)
        sql = SqlParseTool.add_where_str(sql, condition)
        self._read_data(sql)



    def _init_panel(self) -> None:
        """初始面板"""
        _, _, sql_name = self.table_name.get(self.ms_number)
        lbl_name = self.get_label_title(sql_name)
        self.lbl_title.setText(lbl_name)

    # endregion


    # region  工具栏命令，过滤返回， 行选择变化，表单双击
    def action_select(self, q):
        sel = q.text()
        if  sel == '导出':
            pass

        elif sel == '保存':
            self._save_table()

        elif sel == '增加':
            self._add_record()

        elif sel == '插入':
            self._ins_record()

        elif sel == '删除':
            self._del_record()

        elif sel == '排序':
            self._sort_table()

        elif sel == '放弃':
            self._cancel_table()

    @Slot(QModelIndex)
    def on_tableview_double_clicked(self, index):
        """响应表格双击"""
        if index.isValid():
            row = index.row()
            sender = self.sender()  # 获取发送信号的对象
            model = sender.model()
            fid = model.record(row).value('FId')
        else:
            return

        ms_dict = self.DEFAULT_MS_DICT
        if sender.objectName() == 'taskTableView':
            ms_dict = {'msFNumber': '04.21', 'msClass': '10', 'msSaveType': 1, 'FPID': -1}

        elif sender.objectName() == 'potTableView':
            ms_dict = {'msFNumber': '04.01', 'msClass': '11', 'msSaveType': 1, 'FPID': -1}

        if sender.objectName() != 'pickTableView':

            self.create_factory(ms_dict)
            self.create_table_work_class(ms_dict)
            self.work_assistant_re_init()

        self.read_bill_data_for_edit(fid)

    # endregion


    # region 页面数据, 排序选择
    def _read_data(self, sql: str=None) -> None:
        _, _, sql_name = self.table_name.get(self.ms_number)
        if sql is None:
            sql = self.get_sql(sql_name)

        # 先断开旧模型连接（若存在）
        if hasattr(self, 'aloneModel') and self.aloneModel is not None:
            if self._is_data_changed_connected:
                self.aloneModel.dataChanged.disconnect(self.on_table_data_change)
                self._is_data_changed_connected = False  # 重置标志位

        self.aloneModel = self.get_edit_model_by_sql(sql, '')
        self.tableView.setModel(self.aloneModel)
        self.tableView.set_column_width_by_number(self.get_column_width_list(sql_name))


        p_dict = {'widget': self.get_field_widget_list(sql_name)}
        delegate = DefineFeldDelegate(p_dict)
        self.tableView.setItemDelegate(delegate)

        # 仅当未连接时，建立新连接
        if not self._is_data_changed_connected:
            self.aloneModel.dataChanged.connect(self.on_table_data_change)
            self._is_data_changed_connected = True  # 更新标志位


    def on_check_box_state_changed(self, state: int) -> None:
        if state == 2:
            self.tableView.setSortingEnabled(True)      # 开启排序
        else:
            self.tableView.setSortingEnabled(False)     # 关闭排序

    # endregion


    # region 记录增加，插入、删除， model的xh重新排序
    def refresh_fxh(self):
        """重新编号子表的 FXh 字段（从 1 开始连续）"""
        i_col = self.aloneModel.headers.index("FXh")
        # 按源模型行顺序重新编号 FXh
        for row in range(0, self.aloneModel.rowCount()):
            index = self.aloneModel.index(row, i_col)
            self.aloneModel.setData(index, row + 1)

    def _add_record(self) -> None:
        empty_record = QSqlRecord()
        for header in self.aloneModel.headers:
            empty_record.append(QSqlField(header))
        self.aloneModel.appendRecord(empty_record)
        # 滚动到新增行
        last_row = self.aloneModel.rowCount() - 1
        self.tableView.selectRow(last_row)

    def _ins_record(self) -> None:
        """插入记录"""

        selected_rows = self.tableView.selectionModel().selectedRows()
        if not selected_rows:
            DialogUtils.warn("请先选中主表中的一条记录", "警告！")
            return

        insert_row = selected_rows[0].row()
        empty_record = QSqlRecord()
        for header in self.aloneModel.headers:
            empty_record.append(QSqlField(header))

        # 在 insert_row 位置插入
        self.aloneModel.beginInsertRows(QModelIndex(), insert_row, insert_row)
        self.aloneModel.data_rows.insert(insert_row, [None] * len(self.aloneModel.headers))
        self.aloneModel.endInsertRows()
        #
        # 选中新增行
        self.tableView.selectRow(insert_row)

    def _del_record(self) -> None:
        """删除记录"""
        selected_rows = self.tableView.selectionModel().selectedRows()
        if not selected_rows:
            DialogUtils.warn("请先选中表中的一条记录", "警告！")
            return
        row = selected_rows[0].row()
        rec = self.aloneModel.record(row)

        # 确认删除
        reply = DialogUtils.question(f"是否删除 FID={rec.value('FId')}，FNumber={rec.value('FNumber')} 的记录？", "确认删除")

        if reply == StandardButton.Cancel:
            return

        # 删除选中行
        self.aloneModel.removeRecord(row)
        if rec.value('FId') not in [None, '']:
            self.del_set.add(rec.value('FId'))
            self._set_save_button_enabled(True)

    def _sort_table(self) -> None:
        """排序"""
        self.refresh_fxh()

    def _cancel_table(self) -> None:
        """放弃"""
        # 重读数据
        self._read_data()

    # endregion


    # region 保存， 保存命令
    def _save_table(self) -> None:

        # 修改集合中排除删除集合的fid
        self.update_set.difference_update(self.del_set)

        table_name, _, sql_name = self.table_name.get(self.ms_number)
        save_action = SaveTableAction()
        reply, info = save_action.save_table(model=self.aloneModel,
                                       table_name=table_name,
                                       field_list=self.get_field_list(sql_name),
                                       type_list=self.get_field_type_list(sql_name),
                                       join_list=self.get_join_sql_list(sql_name),
                                       update_set=self.update_set,
                                       del_set=self.del_set)
        if reply:
            self.update_set.clear()
            self.del_set.clear()
            self._read_data()
            self._set_save_button_enabled(False)
            self.load_tree()
        else:
            DialogUtils.info('保存出错', '提示', info)


    def on_table_data_change(self, index) -> None:
        """响应model数据变化"""
        self._set_save_button_enabled(True)
        fid = self.aloneModel.record(index.row()).value('FId')
        if fid is not None:
            self.update_set.add(fid)

    # endregion


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    dic = "{'msFNumber':'05.01','msClass':'11', 'msSaveType':1, 'FPID':-1,'inspecType':0}"
    window = OneTableEdit()
    window.show()
    sys.exit(app.exec_())
